import 'package:amap/amap.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'
    hide NavigationRail, NavigationRailDestination;
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import 'dummy_data.dart';

class MapPage extends StatefulWidget {
  @override
  _MapPageState createState() => _MapPageState();
}

class _MapPageState extends State<MapPage> {
  MapModel model;

  @override
  void initState() {
    model = MapModel();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider.value(
      value: model,
      child: Scaffold(
        appBar: AppBar(title: Text("高德地图")),
        body: Stack(
          children: <Widget>[
            MapView(
              controller: model.mapViewController,
              creationParams: model.creationParams,
            ),
            buildIndicator(),
            ApiSubjectNavigationRail(),
          ],
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.clear_all),
          onPressed: resetMap,
        ),
      ),
    );
  }

  void resetMap() async {
    final center = await model.mapViewController.getCenter();
    model.mapViewController
      ..clear()
      ..newLatLngZoom(center, mapDefaultZoom);
  }

  Widget buildIndicator() {
    return Consumer<MapModel>(
      child: Container(
        color: Colors.white,
        child: Center(
          child: CupertinoActivityIndicator(),
        ),
      ),
      builder: (BuildContext context, MapModel value, Widget child) {
        return value.mapLoaded ? Offstage() : child;
      },
    );
  }
}

class MapModel extends ChangeNotifier implements MapEventListener {
  static MapModel of(BuildContext context) =>
      Provider.of(context, listen: false);

  MapCreationParams creationParams;
  MapViewController mapViewController;
  bool mapLoaded = false;

  MapModel() {
    mapViewController = MapViewController(this);
    creationParams = MapCreationParams(
      settings: UiSettings(
        compassEnabled: true,
        myLocationButtonEnabled: true,
        scaleControlsEnabled: true,
        zoomControlsEnabled: true,
      ),
      myLocationStyle: MyLocationStyle(
        myLocationType: MyLocationType.locationRouteNoCenter,
        myLocationIcon: "assets/icons/ico_test.png",
        radiusFillColor: Colors.indigoAccent.withOpacity(0.4).value,
        strokeColor: Colors.red.value,
        strokeWidth: 4.0,
      ),
      cameraPosition: CameraPosition(
        zoom: mapMaxZoom - 2,
      ),
    );
  }

  @override
  void onMapLoaded() {
    mapLoaded = true;
    notifyListeners();
  }

  @override
  void onMarkerClicked(MarkerOptions marker) {
    // TODO: implement onMarkerClicked
  }

  @override
  void onInfoWindowClicked(MarkerOptions marker) {
    // TODO: implement onInfoWindowClicked
  }

  @override
  void onMarkerDragEnd(MarkerOptions marker) {
    // TODO: implement onMarkerDragEnd
  }

  @override
  void onMarkerDragStart(MarkerOptions marker) {
    // TODO: implement onMarkerDragStart
  }

  @override
  void onMarkerDragged(MarkerOptions marker) {
    // TODO: implement onMarkerDragged
  }

  @override
  void onCameraChange(CameraPosition cameraPosition) {
    // TODO: implement onCameraChange
  }

  @override
  void onCameraChangeFinish(CameraPosition cameraPosition) {
    // TODO: implement onCameraChangeFinish
    print("onCameraChangeFinish: $cameraPosition");
  }

  @override
  void onMapClicked(MapClickedEvent event) {
    // TODO: implement onMapClicked
    print(event);
    //mapViewController.addMarker(DummyData.createMarkerData(event));
//    final points = DummyData.createPoints(event.latitude, event.longitude, 10);
//
//    //add center marker
//    mapViewController.addMarker(MarkerOptions(title: "You clicked here")
//      ..position = LatLng(event.latitude, event.longitude));
//    //add markers
//    final markers = DummyData.createMarkerListData(points);
//    mapViewController.addMarkers(markers);

    //add circle
//    points.forEach((p) {
//      mapViewController
//          .addCircle(DummyData.createCircle(p.latitude, p.longitude));
//    });

    //add center circle
    final touchedCircle =
        DummyData.createCircle(event.latitude, event.longitude);
    touchedCircle
      ..fillColor = Colors.purple
      ..strokeColor = Colors.green
      ..radius = 30
      ..strokeWidth = 4.0
      ..strokeDottedLineType = MapConstants.DOTTED_LINE_TYPE_CIRCLE;
    //mapViewController.addCircle(touchedCircle);

    final marker = DummyData.createMarker(event.target);
    mapViewController.addMarker(marker);

//    final polyline = DummyData.createPolyline(points, false);
//    mapViewController.addPolyline(polyline);
  }

  @override
  BuildContext context;
}

class ApiSubjectNavigationRail extends StatefulWidget {
  @override
  _ApiSubjectNavigationRailState createState() =>
      _ApiSubjectNavigationRailState();
}

enum ApiSubject { camera, marker, location, info }

class ApiSubjectItem {
  final ApiSubject subject;
  final String name;
  final IconData icon;
  final WidgetBuilder builder;

  const ApiSubjectItem(
    this.subject,
    this.name,
    this.icon,
    this.builder,
  );
}

final allSubject = <ApiSubjectItem>[
  ApiSubjectItem(
    ApiSubject.camera,
    "Camera",
    Icons.camera_alt,
    (BuildContext context) => MapCameraDemoWidget(),
  ),
  ApiSubjectItem(
    ApiSubject.marker,
    "Marker",
    Icons.format_shapes,
    (BuildContext context) => MapMarkerDemoWidget(),
  ),
  ApiSubjectItem(
    ApiSubject.location,
    "Location",
    Icons.location_searching,
    (BuildContext context) => MapLocationDemoWidget(),
  ),
  ApiSubjectItem(
    ApiSubject.info,
    "Map Info",
    Icons.info_outline,
    (BuildContext context) => MapInfoDemoWidget(),
  ),
];

class _ApiSubjectNavigationRailState extends State<ApiSubjectNavigationRail> {
  ApiSubject subject;
  bool panelExpanded;
  bool hideDetail;

  @override
  void initState() {
    subject = ApiSubject.camera;
    panelExpanded = false;
    hideDetail = true;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        NavigationRail(
          selectedIndex: subject.index,
          minWidth: 56,
          extended: panelExpanded,
          selectedIconTheme: IconThemeData(color: Colors.white, size: 36),
          unselectedIconTheme: IconThemeData(color: Colors.grey, size: 24),
          backgroundColor: Colors.black.withOpacity(0.7),
          selectedLabelTextStyle: TextStyle(fontSize: 20, color: Colors.white),
          unselectedLabelTextStyle:
              TextStyle(fontSize: 16, color: Colors.white),
          destinations: <NavigationRailDestination>[
            for (final it in allSubject)
              NavigationRailDestination(
                icon: Icon(it.icon),
                label: Text(it.name),
              )
          ],
          onDestinationSelected: (int index) {
            setState(() {
              subject = ApiSubject.values[index];
            });
          },
          trailing: IconButton(
            icon: CircleAvatar(
              backgroundColor: Colors.white,
              child: Icon(
                panelExpanded ? Icons.close : Icons.apps,
                color: Colors.purple,
              ),
            ),
            onPressed: () {
              setState(() {
                panelExpanded = !panelExpanded;
              });
            },
          ),
          leading: IconButton(
            icon: Icon(
              hideDetail
                  ? Icons.keyboard_arrow_right
                  : Icons.keyboard_arrow_left,
              color: Colors.white,
              size: 48,
            ),
            onPressed: () {
              setState(() {
                hideDetail = !hideDetail;
              });
            },
          ),
        ),
        if (hideDetail == false)
          Expanded(
            child: Container(
              color: Colors.grey.withOpacity(0.6),
              child: allSubject[subject.index].builder(context),
            ),
          )
      ],
    );
  }
}

class MapCameraDemoWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      scrollDirection: Axis.vertical,
      shrinkWrap: true,
      children: <Widget>[
        ListTile(
          leading: Icon(Icons.zoom_in),
          title: Text("放大地图"),
          onTap: () {
            MapModel.of(context).mapViewController.zoomIn();
          },
        ),
        ListTile(
          leading: Icon(Icons.zoom_out),
          title: Text("缩小地图"),
          onTap: () {
            MapModel.of(context).mapViewController.zoomOut();
          },
        ),
        ListTile(
          leading: Icon(Icons.location_searching),
          title: Text("自动定位到当前位置"),
          onTap: () {
            final mapViewController = MapModel.of(context).mapViewController;
            mapViewController.getZoom()?.then((value) {
              print("current zoom is $value");
            });
            mapViewController.getMyLocation()?.then((location) {
              if (location != null) {
                mapViewController.newCameraPosition(
                  CameraPosition(
                    target: LatLng(
                      location.latitude,
                      location.longitude,
                    ),
                  ),
                );
              }
            });
          },
        ),
      ],
    );
  }
}

class MapMarkerDemoWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      shrinkWrap: true,
      children: <Widget>[
        ListTile(
          title: Text("添加一个图标"),
          onTap: () async {
            final mapViewController = MapModel.of(context).mapViewController;
            final center = await mapViewController.getCenter();
            final marker = DummyData.createMarker(center.random());
            mapViewController.addMarker(marker);
          },
        ),
        ListTile(
          title: Text("添加一些折线"),
          onTap: () async {
            final mapViewController = MapModel.of(context).mapViewController;
            final center = await mapViewController.getCenter();
            final polyling = DummyData.createPolyline(
                DummyData.createPoints(center, 10), true);
            mapViewController.addPolyline(polyling);
            mapViewController.zoomTo(mapMaxZoom - 2);
          },
        ),
      ],
    );
  }
}

class MapLocationDemoWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      shrinkWrap: true,
      children: <Widget>[
        ListTile(
          title: Text("定位到当前位置, zoom不变"),
          onTap: () async {
            final mapViewController = MapModel.of(context).mapViewController;
            final myLocation = await mapViewController.getMyLocation();
            mapViewController.newLatLng(myLocation.target);
          },
        ),
        ListTile(
          title: Text("定位到当前位置 + zoom值变最大"),
          onTap: () async {
            final mapViewController = MapModel.of(context).mapViewController;
            final myLocation = await mapViewController.getMyLocation();
            mapViewController.newLatLngZoom(myLocation.target, mapMaxZoom);
          },
        ),
        ListTile(
          title: Text("定位到当前位置 + zoom值变默认"),
          onTap: () async {
            final mapViewController = MapModel.of(context).mapViewController;
            final myLocation = await mapViewController.getMyLocation();
            mapViewController.newLatLngZoom(myLocation.target, mapDefaultZoom);
          },
        ),
      ],
    );
  }
}

class MapInfoDemoWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
